package services

import (
	"context"
	"encoding/json"
	"go_ruoyi/global"
	"go_ruoyi/model/db_model"
	"go_ruoyi/model/request_model"
	"go_ruoyi/model/response_model"
	"go_ruoyi/utils"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

func LoginService(c *gin.Context) {
	// 获取请求参数
	var (
		login request_model.Login
		user  db_model.User
	)
	if err := c.ShouldBindJSON(&login); err != nil {
		response_model.ParameterError(c)
		return
	}

	//检验验证码
	if !utils.VerifyCode(login.Code, login.Uuid) {
		response_model.FailWithMsg(c, "验证码错误")
		return
	}
	TX := global.DB.Begin()
	if err := TX.Where("user_name = ?", login.Username).Preload("Roles.Menus").Preload("Posts").First(&user).Error; err != nil {
		response_model.FailWithMsg(c, "当前用户不存在")
		return
	}
	if err := TX.Where("user_id = ?", user.UserId).Updates(&db_model.User{
		LoginDate: time.Now(),
		LoginIp:   c.ClientIP(),
	}).Error; err != nil {
		response_model.FailWithMsg(c, "更新登录信息失败")
		return
	}
	TX.Commit()
	if err := user.DecryptionPassword(login.Password); err != nil {
		response_model.FailWithMsg(c, "密码错误")
		return
	}
	permissions := make([]string, 0)
	roles := make([]string, 0)
	for _, v := range user.Roles {
		roles = append(roles, v.RoleKey)
		for _, v1 := range v.Menus {
			if v1.MenuType == "C" {
				permissions = append(permissions, v1.Perms)
			}

		}
	}
	permissions = utils.UniqueSlice(permissions)
	user.Roles = user.Roles[:0]

	uuId := uuid.NewString()
	exp := time.Duration(global.Viper.GetInt("tokenExpirationTime")) * time.Minute
	dataStr, _ := json.Marshal(gin.H{
		"permissions": permissions,
		"roles":       roles,
		"user":        user,
	})
	global.Redis.Set(context.Background(), uuId, dataStr, exp)

	token, err := utils.CreateToken(user.UserId, user.UserName, uuId)
	if err != nil {
		response_model.FailWithMsg(c, "token生成失败")
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":  200,
		"token": token,
		"msg":   "操作成功",
	})

}

func GetInfoService(c *gin.Context) {
	var (
		user db_model.User
	)
	userId, _ := c.Get("userId")

	if err := global.DB.Where("user_id = ?", userId).Preload("Roles").Preload("Roles.Menus").Preload("Posts").First(&user).Error; err != nil {
		response_model.FailWithMsg(c, "服务器异常")
	}
	permissions := make([]string, 0)
	roles := make([]string, 0)
	for _, v := range user.Roles {
		roles = append(roles, v.RoleKey)
		for _, v1 := range v.Menus {
			if v1.MenuType == "C" || v1.MenuType == "F" {
				permissions = append(permissions, v1.Perms)
			}

		}
	}
	permissions = utils.UniqueSlice(permissions)
	user.Roles = user.Roles[:0]
	c.JSON(http.StatusOK, gin.H{
		"code":        200,
		"msg":         "操作成功",
		"permissions": permissions,
		"roles":       roles,
		"user":        user,
	})
}

func GetRouters(c *gin.Context) {
	var (
		user db_model.User
		menu []db_model.Menu
	)
	userId, _ := c.Get("userId")
	if err := global.DB.Preload("Roles.Menus").Where("user_id = ?", userId).First(&user).Error; err != nil {
		response_model.FailWithMsg(c, "服务器异常")
		return
	}
	for _, role := range user.Roles {
		menu = append(menu, role.Menus...)
	}
	treeMenu := TreeMenu(UniqueMenu(menu))
	response_model.OK(c, treeMenu)
}

func LoginOut(c *gin.Context) {
	tokenString := c.GetHeader("Authorization")
	userMap, _ := utils.ParseToken(tokenString)
	global.Redis.Set(context.Background(), userMap["tokenId"].(string), "", 1)
	response_model.OK(c, "退出成功")
}
